package space.xxhui;

import org.apache.commons.exec.CommandLine;
import org.apache.commons.exec.DefaultExecutor;
import org.apache.commons.exec.PumpStreamHandler;

import java.io.ByteArrayOutputStream;
import java.io.IOException;

public class VideoToImagesAndAudio {

    public static void main(String[] args) {
        String inputVideo = "D:\\myDownload\\youtube_32_tWcivxsw_1920x1080_h264.mp4";  // 输入视频文件
        String outputImagePattern = "E:\\data\\videoConvert\\output_%05d.bmp";  // 输出图片文件名模式
        String outputAudio = "E:\\data\\videoConvert\\output_audio.mp3";  // 输出音频文件
        //convertVideoToImage(inputVideo, outputImagePattern);
        convertVideoToReverseImage(inputVideo, outputImagePattern);
        convertVideoToAudio(inputVideo, outputAudio);
    }

    public static boolean convertVideoToAudio(String inputVideo, String outputAudio) {
        boolean result = true;
        // 提取音频
        CommandLine audioCmdLine = new CommandLine("ffmpeg");
        audioCmdLine.addArgument("-i"); // 输入文件
        audioCmdLine.addArgument(inputVideo);
        audioCmdLine.addArgument("-t"); //截取前10秒
        audioCmdLine.addArgument("10");
        audioCmdLine.addArgument("-q:a");
        audioCmdLine.addArgument("0");
        audioCmdLine.addArgument("-map");
        audioCmdLine.addArgument("a");
        audioCmdLine.addArgument(outputAudio);

        // 创建执行器
        DefaultExecutor executor = new DefaultExecutor();
        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
        ByteArrayOutputStream errorStream = new ByteArrayOutputStream();
        PumpStreamHandler streamHandler = new PumpStreamHandler(outputStream, errorStream);
        executor.setStreamHandler(streamHandler);
        try {
            // 执行提取音频命令
            int exitCode = executor.execute(audioCmdLine);

            // 输出命令执行结果
            System.out.println("FFmpeg 输出: " + outputStream);
            System.out.println("FFmpeg 错误: " + errorStream);

            // 检查退出码
            if (exitCode == 0) {
                System.out.println("audioExitCode=0 执行成功");
            } else {
                System.err.println("FFmpeg 执行失败，退出码: " + exitCode);
                result = false;
            }
            System.out.println("视频已成功转换为图片和音频！");
        } catch (IOException e) {
            e.printStackTrace();
            result = false;
        }
        return result;
    }

    public static boolean convertVideoToImage(String inputVideo, String outputImagePattern) {
        boolean result = true;
        // 将视频逐帧转换为图片
        // 构建 FFmpeg 命令
        CommandLine cmdLine = new CommandLine("ffmpeg");
        cmdLine.addArgument("-i"); // 输入文件
        cmdLine.addArgument(inputVideo);
        cmdLine.addArgument("-t"); //截取前10秒
        cmdLine.addArgument("10");
        cmdLine.addArgument("-r"); // 每10帧截取一张图片
        cmdLine.addArgument("30");
        cmdLine.addArgument(outputImagePattern); // 输出图片格式

        // 创建执行器
        DefaultExecutor executor = new DefaultExecutor();
        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
        ByteArrayOutputStream errorStream = new ByteArrayOutputStream();
        PumpStreamHandler streamHandler = new PumpStreamHandler(outputStream, errorStream);
        executor.setStreamHandler(streamHandler);
        try {
            // 执行提取图片命令
            // 执行命令
            outputStream.reset();
            errorStream.reset();
            int exitCode = executor.execute(cmdLine);

            // 输出命令执行结果
            System.out.println("FFmpeg 输出: " + outputStream);
            System.out.println("FFmpeg 错误: " + errorStream);

            // 检查退出码
            if (exitCode == 0) {
                System.out.println("exitCode=0 执行成功");
            } else {
                System.err.println("FFmpeg 执行失败，退出码: " + exitCode);
                result = false;
            }
        } catch (IOException e) {
            e.printStackTrace();
            result = false;
        }
        return result;
    }

    public static boolean convertVideoToReverseImage(String inputVideo, String outputImagePattern) {
        boolean result = true;
        // 将视频逐帧转换为图片
        // 构建 FFmpeg 命令
        CommandLine cmdLine = new CommandLine("ffmpeg");
        cmdLine.addArgument("-i"); // 输入文件
        cmdLine.addArgument(inputVideo);
        cmdLine.addArgument("-vf"); //截取前10秒
        cmdLine.addArgument("\"trim=0:10,reverse\"");
        cmdLine.addArgument("-r"); // 每10帧截取一张图片
        cmdLine.addArgument("30");
        cmdLine.addArgument(outputImagePattern); // 输出图片格式

        // 创建执行器
        DefaultExecutor executor = new DefaultExecutor();
        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
        ByteArrayOutputStream errorStream = new ByteArrayOutputStream();
        PumpStreamHandler streamHandler = new PumpStreamHandler(outputStream, errorStream);
        executor.setStreamHandler(streamHandler);
        try {
            // 执行提取图片命令
            // 执行命令
            outputStream.reset();
            errorStream.reset();
            int exitCode = executor.execute(cmdLine);

            // 输出命令执行结果
            System.out.println("FFmpeg 输出: " + outputStream);
            System.out.println("FFmpeg 错误: " + errorStream);

            // 检查退出码
            if (exitCode == 0) {
                System.out.println("exitCode=0 执行成功");
            } else {
                System.err.println("FFmpeg 执行失败，退出码: " + exitCode);
                result = false;
            }
        } catch (IOException e) {
            e.printStackTrace();
            result = false;
        }
        return result;
    }

}
